<template>
<div :class="props.disabled?'tinymacClass':''">
	<editor ref="zhEditorRef" v-model="myValue" :disabled="props.disabled" :init="init"  :id="tinymceId"></editor>
</div>
</template>

<script setup lang="ts" name="zhEditor">
import {ElMessage } from 'element-plus'
//JS部分
//在js中引入所需的主题和组件
import tinymce from 'tinymce/tinymce'
import 'tinymce/skins/content/default/content.css'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver'
import 'tinymce/themes/silver/theme'
import 'tinymce/icons/default'; //引入编辑器图标icon，不引入则不显示对应图标
import 'tinymce/models/dom' // 这里是个坑 一定要引入
//在TinyMce.vue中接着引入相关插件
import "tinymce/icons/default/icons"
import 'tinymce/plugins/advlist'; //高级列表
import 'tinymce/plugins/anchor'; //锚点
import 'tinymce/plugins/autolink'; //自动链接
import 'tinymce/plugins/autoresize'; //编辑器高度自适应,注：plugins里引入此插件时，Init里设置的height将失效
import 'tinymce/plugins/autosave'; //自动存稿
import 'tinymce/plugins/charmap'; //特殊字符
import 'tinymce/plugins/code'; //编辑源码
import 'tinymce/plugins/codesample'; //代码示例
import 'tinymce/plugins/directionality'; //文字方向
import 'tinymce/plugins/emoticons'; //表情
import 'tinymce/plugins/fullscreen'; //全屏
import 'tinymce/plugins/help'; //帮助
import 'tinymce/plugins/image'; //插入编辑图片
import 'tinymce/plugins/importcss'; //引入css
import 'tinymce/plugins/insertdatetime'; //插入日期时间
import 'tinymce/plugins/link'; //超链接
import 'tinymce/plugins/lists'; //列表插件
import 'tinymce/plugins/media'; //插入编辑媒体
import 'tinymce/plugins/nonbreaking'; //插入不间断空格
import 'tinymce/plugins/pagebreak'; //插入分页符
import 'tinymce/plugins/preview'; //预览
import 'tinymce/plugins/quickbars'; //快速工具栏
import 'tinymce/plugins/save'; //保存
import 'tinymce/plugins/searchreplace'; //查找替换
// import 'tinymce/plugins/spellchecker'  //拼写检查，暂未加入汉化，不建议使用
import 'tinymce/plugins/table'; //表格
import 'tinymce/plugins/template'; //内容模板
import 'tinymce/plugins/visualblocks'; //显示元素范围
import 'tinymce/plugins/visualchars'; //显示不可见字符
import 'tinymce/plugins/wordcount'; //字数统计
//这里我选择将数据定义在props里面，方便在不同的页面也可以配置出不同的编辑器，当然也可以直接在组件中直接定义
let publicUrl = import.meta.env.VITE_PUBLIC_PATH;
if (publicUrl === '/') {
	publicUrl = '';
}
const props = defineProps({
  modelValue: {
    type: String,
    default: () => {
      return ""
    },
  },
  placeholder: {
    type: String,
    default: "请输入内容",
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  //文件分类
  fileClassCode: {
		type: String,
		default: '97',
	},
  plugins: {
    type: [String, Array],
    default: "preview searchreplace autolink directionality visualblocks visualchars fullscreen image importcss link media template code codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave",
  },//必填
  toolbar: {
    type: [String, Array],
    default:
      "fullscreen undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
                styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
                table image media charmap emoticons hr pagebreak insertdatetime print preview | code selectall | indent2em lineheight formatpainter axupimgs",
  },//必填
  menubar: {
    type: [Boolean, String],
    default:
      "file edit insert view format table tools",
  },//必填
  height: {
    type: String,
    default: '560px',
  },
})
const emits = defineEmits(["update:modelValue"])
const zhEditorRef=ref<any>();
//用于接收外部传递进来的富文本
const myValue = ref(props.modelValue)
const tinymceId = ref("vue-tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + ""))
//定义一个对象 init初始化
const init = reactive({
  selector: '#' + tinymceId.value, //富文本编辑器的id,
  language_url: publicUrl+'/tinymce/langs/zh-Hans.js', // 语言包的路径，具体路径看自己的项目，文档后面附上中文js文件
  language: "zh-Hans", //语言
  skin_url: publicUrl+'/tinymce/skins/ui/oxide', // skin路径，具体路径看自己的项目
  height: props.height, //编辑器高度 注：引入autoresize插件时，此属性失效
  branding: true, //是否禁用“Powered by TinyMCE” tiny技术支持信息是否显示
  resize: false, //编辑器宽高是否可变，false-否,true-高可变，'both'-宽高均可，注意引号
  statusbar: false, //最下方的元素路径和字数统计那一栏是否显示
  elementpath: false, //元素路径是否显示
  promotion: false,
  menubar: props.menubar, //顶部菜单栏显示'file edit insert view format table tools', //菜单栏配置，设为false则隐藏，不配置则默认显示全部菜单，也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单”
  image_dimensions: true, //去除宽高属性
  placeholder:props.placeholder,
  plugins: props.plugins,  //这里的数据是在props里面就定义好了的
  toolbar: props.toolbar, //这里的数据是在props里面就定义好了的
  font_formats: "Arial=arial,helvetica,sans-serif; 宋体=SimSun,serif; 微软雅黑=Microsoft Yahei,Helvetica Neue,PingFang SC,sans-serif;楷体='楷体';隶书='隶书';幼圆='幼圆';苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino; Impact=impact,chicago;", //字体
  fontsize_formats: '11px 12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 64px 72px', //文字大小
  // paste_convert_word_fake_lists: false, // 插入word文档需要该属性
  paste_webkit_styles: "all",
  a11y_advanced_options: true,
  image_caption: true,
  paste_data_images: true, 
  image_uploadtab: true,
  paste_merge_formats: true,
  nonbreaking_force_tab: false,
  paste_auto_cleanup_on_paste: false,
  file_picker_types: 'file image media',
  content_css: publicUrl+'/tinymce/skins/content/default/content.css', //以css文件方式自定义可编辑区域的css样式，css文件需自己创建并引入
  //图片上传
  images_upload_handler: (blobInfo, success) => new Promise((resolve, reject) => {
    if (blobInfo.blob().size / 1024 / 1024 < 1) {
      let base64 = "data:image/png;base64," + blobInfo.base64();
      resolve(base64)
      return
    }
    if (blobInfo.blob().size / 1024 / 1024 > 10) {
      reject({ message: '上传失败，图片大小请控制在 10M 以内', remove: true })
      return
    } else {
      let formData = new FormData();
			formData.append('file', blobInfo.blob());
      let fileInfo = {
        uploaderId: $store.user.userInfo?.userId,
        uploader: $store.user.userInfo?.fullName,
        fileClassCode: props.fileClassCode,
      };
      formData.append('fileInfo', JSON.stringify(fileInfo));
      
    let fileUploadUrl=$api.common.fileUploadUrl.url
    $http.uploadFile(fileUploadUrl, formData)
			.then((res) => {
				if (res.result.file.flag) {
					let showId = res.result.file.showId;
					let path = $api.common.fileShowUrl.url + showId;
					resolve(path)  //上传成功，在成功函数里填入图片路径
				} else {
					reject('HTTP Error: 上传失败' + res.result?.file?.msg);
          return
				}
			})
			.catch((err) => {
        reject('上传出错:'+err.message||'服务器异常')
        return
			});
    }
  }),

  // 文件上传
  file_picker_callback: (callback, value, meta) => {
    //,,m4v,avi,wmv,rmvb,mov,mpg,mpeg,webm
    let filetype =
      ".pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4,.mkv, .avi,.wmv, .rmvb,.mov,.mpg,.mpeg,.webm, .jpg, .jpeg, .png, .gif"; //限制文件的上传类型
    let inputElem = document.createElement("input"); //创建文件选择
    inputElem.setAttribute("type", "file");
    inputElem.setAttribute("accept", filetype);
    inputElem.click();
    inputElem.onchange = () => {
      let file = inputElem.files[0]; //获取文件信息
      let params = new FormData();
      if (meta.filetype == "media") {
        //判断文件类型
        params.append("file", file);
      } else if (meta.filetype == "image") {
        params.append("file", file);
      } else {
        params.append("file", file);
      }
      
      let fileInfo = {
        uploaderId: $store.user.userInfo?.userId,
        uploader: $store.user.userInfo?.fullName,
        fileClassCode: props.fileClassCode,
      };
      params.append('fileInfo', JSON.stringify(fileInfo));
      
      if (meta.filetype == "image" && file.size / 1024 / 1024 > 5) {
        ElMessage.error("上传失败，图片大小请控制在5M以内");
      } else if (
        meta.filetype == "media" &&
        file.size / 1024 / 1024 > 500
      ){
        ElMessage.error("上传失败，视频大小请控制在 500M 以内");
      } else if (
        meta.filetype == "file" &&
        file.size / 1024 / 1024 > 50
      ){
         ElMessage.error("上传失败，文件大小请控制在 50M 以内");
      } else {
        let fileUploadUrl=$api.common.fileUploadUrl.url
    $http.uploadFile(fileUploadUrl, params)
			.then((res) => {
				if (res.result.file.flag) {
					let showId = res.result.file.showId;
					let path = $api.common.fileShowUrl.url + showId;
					callback(path)  //上传成功，在成功函数里填入图片路径
				} else {
					callback('HTTP Error: 上传失败' + res.result?.file?.msg);
          
				}
			})
			.catch(() => {
        ElMessage.error("上传出错，服务器开小差了呢");
        
			});
      
      }
    };
  },
})

//监听外部传递进来的的数据变化
watch(
  () => props.modelValue,
  () => {
    myValue.value = props.modelValue
  }
)
//监听富文本中的数据变化
watch(
  () => myValue.value,
  () => {
    emits("update:modelValue", myValue.value)
  }
)
//在onMounted中初始化编辑器
onMounted(() => {
  nextTick(()=>{
    tinymce.init({})
  })
  
})
</script>
<style  lang="scss">
.tinymacClass {
    position: relative;
    left: 0;
    top: 0;
    opacity: 0.5;
    width: 100%;
    height: 100%;
    background: #000;
    z-index: 998;
    pointer-events: none;
}
</style>
